home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 367_01 / futi14as.zoo / getdate.y < prev    next >
Text File  |  1992-02-22  |  15KB  |  661 lines

  1. %token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO DST
  2. %{
  3.     /*     Originally from: Steven M. Bellovin (unc!smb)    */ 
  4.     /*    Dept. of Computer Science            */
  5.     /*    University of North Carolina at Chapel Hill    */
  6.     /*    @(#)getdate.y    2.17    11/30/87            */
  7.  
  8. /* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
  9.    This port is also distributed under the terms of the
  10.    GNU General Public License as published by the
  11.    Free Software Foundation.
  12.  
  13.    Please note that this file is not identical to the
  14.    original GNU release, you should have received this
  15.    code as patch to the official release.  */
  16.  
  17. #ifdef MSDOS
  18. static char RCS_Id[] =
  19.   "$Header: e:/gnu/fileutil/RCS/getdate.y 1.4.0.2 90/09/19 12:27:47 tho Exp $";
  20. #endif /* MSDOS */
  21.  
  22. /* #include "defs.h" JF not used any more */
  23. #include <sys/types.h>
  24. #ifdef USG
  25. struct timeb
  26. {
  27.     time_t    time;
  28.     unsigned short millitm;
  29.     short    timezone;
  30.     short    dstflag;
  31. };
  32. static void ftime ();
  33. #else
  34. #include <sys/timeb.h>
  35. #endif
  36. #include <ctype.h>
  37.  
  38. #if defined(BSD4_2) || defined (BSD4_1C)
  39. #include <sys/time.h>
  40. #else /* sane */
  41. #include <time.h>
  42. #endif /* sane */
  43.  
  44. #if defined (STDC_HEADERS) || defined (USG)
  45. #include <string.h>
  46. #endif
  47.  
  48. #ifdef __GNUC__
  49. #define alloca __builtin_alloca
  50. #else
  51. #ifdef sparc
  52. #include <alloca.h>
  53. #endif
  54. #endif
  55.  
  56. #ifdef MSDOS
  57. #include <malloc.h>
  58. int getdate_yyparse (void);
  59. long getdate (char *p, struct timeb *now);
  60. void ftime (struct timeb *timeb);
  61. static long dateconv (int mm, int dd, int yy, int h, int m, int s, int mer,
  62.               int zone, int dayflag);
  63. static long dayconv (int ord, int day, long now);
  64. static long timeconv (int hh, int mm, int ss, int mer);
  65. static long monthadd (long sdate, long relmonth);
  66. static long daylcorr (long future, long now);
  67. static int lookup (char *id);
  68. static int yyerror (char *s);
  69. static int yylex (void);
  70. #endif /* MSDOS */
  71.  
  72. #ifndef NULL
  73. #define    NULL    0
  74. #endif
  75. #define daysec (24L*60L*60L)
  76.     static int timeflag, zoneflag, dateflag, dayflag, relflag;
  77.     static time_t relsec, relmonth;
  78.     static int hh, mm, ss, merid, day_light;
  79.     static int dayord, dayreq;
  80.     static int month, day, year;
  81.     static int ourzone;
  82. #define AM 1
  83. #define PM 2
  84. #define DAYLIGHT 1
  85. #define STANDARD 2
  86. #define MAYBE    3
  87.  
  88. static time_t timeconv();
  89. static time_t daylcorr();
  90. static lookup();
  91.  
  92. static int yylex ();
  93. #define yyparse getdate_yyparse
  94. static int yyerror ();
  95.  
  96. %}
  97.  
  98. %%
  99. timedate:         /* empty */
  100.     | timedate item
  101.     ;
  102.  
  103. item:    tspec
  104.         {timeflag++;}
  105.     | zone
  106.         {zoneflag++;}
  107.     | dtspec
  108.         {dateflag++;}
  109.     | dyspec
  110.         {dayflag++;}
  111.     | rspec
  112.         {relflag++;}
  113.     | nspec;
  114.  
  115. nspec:    NUMBER
  116.         {if (timeflag && dateflag && !relflag) year = $1;
  117.         else if ($1 > 10000) {
  118.             dateflag++;
  119.             day= $1%100;
  120.             month= ($1/100)%100;
  121.             year = month/10000;
  122.         } else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
  123.  
  124. tspec:    NUMBER MERIDIAN
  125.         {hh = $1; mm = 0; ss = 0; merid = $2;}
  126.     | NUMBER ':' NUMBER
  127.         {hh = $1; mm = $3; merid = 24;}
  128.     | NUMBER ':' NUMBER MERIDIAN
  129.         {hh = $1; mm = $3; merid = $4;}
  130.     | NUMBER ':' NUMBER NUMBER
  131.         {hh = $1; mm = $3; merid = 24;
  132.         day_light = STANDARD; ourzone = -($4%100 + 60*($4/100));}
  133.     | NUMBER ':' NUMBER ':' NUMBER
  134.         {hh = $1; mm = $3; ss = $5; merid = 24;}
  135.     | NUMBER ':' NUMBER ':' NUMBER MERIDIAN
  136.         {hh = $1; mm = $3; ss = $5; merid = $6;}
  137.     | NUMBER ':' NUMBER ':' NUMBER NUMBER
  138.         {hh = $1; mm = $3; ss = $5; merid = 24;
  139.         day_light = STANDARD; ourzone = -($6%100 + 60*($6/100));};
  140.  
  141. zone:    ZONE dst
  142.         {ourzone = $1; day_light = $2;}
  143.     | DAYZONE
  144.         {ourzone = $1; day_light = DAYLIGHT;};
  145.  
  146. dst:    /* empty */
  147.         { $$ = STANDARD; }
  148.     | DST
  149.         { $$ = DAYLIGHT; };
  150.  
  151. dyspec:    DAY
  152.         {dayord = 1; dayreq = $1;}
  153.     | DAY ','
  154.         {dayord = 1; dayreq = $1;}
  155.     | NUMBER DAY
  156.         {dayord = $1; dayreq = $2;};
  157.  
  158. dtspec:    NUMBER '/' NUMBER
  159.         {month = $1; day = $3;}
  160.     | NUMBER '/' NUMBER '/' NUMBER
  161.         {month = $1; day = $3; year = $5;}
  162.     | MONTH NUMBER
  163.         {month = $1; day = $2;}
  164.     | MONTH NUMBER ',' NUMBER
  165.         {month = $1; day = $2; year = $4;}
  166.     | NUMBER MONTH
  167.         {month = $2; day = $1;}
  168.     | NUMBER MONTH NUMBER
  169.         {month = $2; day = $1; year = $3;};
  170.  
  171.  
  172. rspec:    NUMBER UNIT
  173.         {relsec +=  60L * $1 * $2;}
  174.     | NUMBER MUNIT
  175.         {relmonth += $1 * $2;}
  176.     | NUMBER SUNIT
  177.         {relsec += $1;}
  178.     | UNIT
  179.         {relsec +=  60L * $1;}
  180.     | MUNIT
  181.         {relmonth += $1;}
  182.     | SUNIT
  183.         {relsec++;}
  184.     | rspec AGO
  185.         {relsec = -relsec; relmonth = -relmonth;};
  186. %%
  187.  
  188. static int mdays[12] =
  189.     {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
  190. #define epoch 1970
  191.  
  192. extern struct tm *localtime();
  193.  
  194. static time_t
  195. dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
  196. int mm, dd, yy, h, m, s, mer, zone, dayflag;
  197. {
  198.     time_t tod, jdate;
  199.     register int i;
  200.  
  201.     if (yy < 0) yy = -yy;
  202.     if (yy < 100) yy += 1900;
  203.     mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
  204.     if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
  205.         dd < 1 || dd > mdays[--mm]) return (-1);
  206.     jdate = dd-1;
  207.         for (i=0; i<mm; i++) jdate += mdays[i];
  208.     for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
  209.     jdate *= daysec;
  210.     jdate += zone * 60L;
  211.     if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
  212.     jdate += tod;
  213.     if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
  214.         jdate += -1*60*60;
  215.     return (jdate);
  216. }
  217.  
  218. static time_t
  219. dayconv(ord, day, now)
  220. int ord, day; time_t now;
  221. {
  222.     register struct tm *loctime;
  223.     time_t tod;
  224.  
  225.     tod = now;
  226.     loctime = localtime(&tod);
  227.     tod += daysec * ((day - loctime->tm_wday + 7) % 7);
  228.     tod += 7*daysec*(ord<=0?ord:ord-1);
  229.     return daylcorr(tod, now);
  230. }
  231.  
  232. static time_t
  233. timeconv(hh, mm, ss, mer)
  234. register int hh, mm, ss, mer;
  235. {
  236.     if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
  237.     switch (mer) {
  238.         case AM: if (hh < 1 || hh > 12) return(-1);
  239.              return (60L * ((hh%12)*60L + mm)+ss);
  240.         case PM: if (hh < 1 || hh > 12) return(-1);
  241.              return (60L * ((hh%12 +12)*60L + mm)+ss);
  242.         case 24: if (hh < 0 || hh > 23) return (-1);
  243.              return (60L * (hh*60L + mm)+ss);
  244.         default: return (-1);
  245.     }
  246. }
  247.  
  248. static time_t
  249. monthadd(sdate, relmonth)
  250. time_t sdate, relmonth;
  251. {
  252.     struct tm *ltime;
  253.     time_t dateconv();
  254.     int mm, yy;
  255.  
  256.     if (relmonth == 0) return 0;
  257.     ltime = localtime(&sdate);
  258.     mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
  259.     yy = mm/12;
  260.     mm = mm%12 + 1;
  261.     return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
  262.         ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
  263. }
  264.  
  265. static time_t
  266. daylcorr(future, now)
  267. time_t future, now;
  268. {
  269.     int fdayl, nowdayl;
  270.  
  271.     nowdayl = (localtime(&now)->tm_hour+1) % 24;
  272.     fdayl = (localtime(&future)->tm_hour+1) % 24;
  273.     return (future-now) + 60L*60L*(nowdayl-fdayl);
  274. }
  275.  
  276. static char *lptr;
  277.  
  278. static int
  279. yylex()
  280. {
  281.     extern int yylval;
  282.     int sign;
  283.     register char c;
  284.     register char *p;
  285.     char idbuf[20];
  286.     int pcnt;
  287.  
  288.     for (;;) {
  289.         while (isspace(*lptr))
  290.             lptr++;
  291.  
  292.         if (isdigit(c = *lptr) || c == '-' || c == '+') {
  293.             if (c== '-' || c == '+') {
  294.                 if (c=='-') sign = -1;
  295.                 else sign = 1;
  296.                 if (!isdigit(*++lptr)) {
  297.                     /* yylval = sign; return (NUMBER); */
  298.                     return yylex();    /* skip the '-' sign */
  299.                 }
  300.             } else sign = 1;
  301.             yylval = 0;
  302.             while (isdigit(c = *lptr++))
  303.                 yylval = 10*yylval + c - '0';
  304.             yylval *= sign;
  305.             lptr--;
  306.             return (NUMBER);
  307.  
  308.         } else if (isalpha(c)) {
  309.             p = idbuf;
  310.             while (isalpha(c = *lptr++) || c=='.')
  311.                 if (p < &idbuf[sizeof(idbuf)-1]) *p++ = c;
  312.             *p = '\0';
  313.             lptr--;
  314.             return (lookup(idbuf));
  315.         }
  316.  
  317.         else if (c == '(') {
  318.             pcnt = 0;
  319.             do {
  320.                 c = *lptr++;
  321.                 if (c == '\0') return(c);
  322.                 else if (c == '(') pcnt++;
  323.                 else if (c == ')') pcnt--;
  324.             } while (pcnt > 0);
  325.         }
  326.  
  327.         else return (*lptr++);
  328.     }
  329. }
  330.  
  331. struct table {
  332.     char *name;
  333.     int type, value;
  334. };
  335.  
  336. static struct table mdtab[] = {
  337.     {"january", MONTH, 1},
  338.     {"february", MONTH, 2},
  339.     {"march", MONTH, 3},
  340.     {"april", MONTH, 4},
  341.     {"may", MONTH, 5},
  342.     {"june", MONTH, 6},
  343.     {"july", MONTH, 7},
  344.     {"august", MONTH, 8},
  345.     {"september", MONTH, 9},
  346.     {"sept", MONTH, 9},
  347.     {"october", MONTH, 10},
  348.     {"november", MONTH, 11},
  349.     {"december", MONTH, 12},
  350.  
  351.     {"sunday", DAY, 0},
  352.     {"monday", DAY, 1